#pragma once

#include <string>


namespace evm {

using namespace std;

struct Digest {
    Digest(const string& name);

    ~Digest();

    Digest& update(const string& arg);

    const string& digest();
    const string& hexdigest();

private:
    void* mdctx_;
    bool digested_{};
    string digest_;
    bool hexdigested_{};
    string hexdigest_;
};

struct FileDigest : Digest {
    FileDigest(const string& name, const string& file_name);
};

inline Digest md5() {
    return Digest("md5");
}

inline Digest sha1() {
    return Digest("sha1");
}

inline Digest sha256() {
    return Digest("sha256");
}

inline Digest sha512() {
    return Digest("sha512");
}

inline FileDigest md5(const string& file_name) {
    return FileDigest("md5", file_name);
}

inline FileDigest sha1(const string& file_name) {
    return FileDigest("sha1", file_name);
}

inline FileDigest sha256(const string& file_name) {
    return FileDigest("sha256", file_name);
}

inline FileDigest sha512(const string& file_name) {
    return FileDigest("sha512", file_name);
}

}
